# 47. subprocess模块

# subprocess模块

subprocess模块在这里暂时不会讲太多

# 使用subprocess模块来操作系统的命令

在这里使用subprocess模块中的popen类,这里先说一下,要使用的命令跟类的参数

import subprocess
sp = subprocess.Popen("cmd",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# cmd : 代表系统命令
# shell = True   代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行
# stdout   是执行完系统命令之后,用于保存结果的一个管道
# stderr   是执行完系统命令之后,用于保存错误结果的一个管道

## 执行命令得到的结果要怎么看
sp.stdout.read()  ##查看系统命令执行成功后的结果
sp.stderr.read()  ##查看系统命令执行错误后的结果

## 注意:在stdout跟stderr的结果只允许获取一次,简单说,就是你获取一次stdout的结果,那么在获取一次,就是为空
## 所以目前一般都是用变量的赋值,让获取到的值可以进行多次利用
stdout = r.stdout.read()
stderr = r.stderr.read()

## 注意,当前的环境是win10,在执行命令后得到的结果是bytes类型的,想看真正的结果,要进行转码
stdout = r.stdout.read().decode("gbk")
stderr = r.stderr.read().decode("gbk")

# 简单的练习题

通过socket模块,简单实现,可以在客户端操作服务端的操作系统

## 服务端的代码 server.py
import socket
import subprocess
sk = socket.socket()
sk.bind(("127.0.0.1",18080))
sk.listen()
conn,addr = sk.accept()
while 1:
    ret = conn.recv(102400).decode("utf-8")
    sp = subprocess.Popen(ret,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    sp_stdout = sp.stdout.read()
    sp_stderr = sp.stderr.read()
    if sp_stdout:
        conn.send(sp_stdout)
    elif sp_stderr:
        conn.send(sp_stderr)
    else:
        conn.send("出错".encode("gbk"))
conn.close()
sk.close()


## 客户端的代码 client.py
import socket
sk = socket.socket()
sk.connect(("127.0.0.1",18080))
while 1:
    user = input("请输入命令:")
    sk.send(user.encode("utf-8"))
    ret = sk.recv(1024000).decode("gbk")
    print(ret)
sk.close()